package io.chenglicun.modules.clc.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import io.chenglicun.common.page.PageData;
import io.chenglicun.common.service.impl.CrudServiceImpl;
import io.chenglicun.common.utils.ConvertUtils;
import io.chenglicun.modules.clc.dao.ClcExamReleaseDao;
import io.chenglicun.modules.clc.dao.ClcExamResultDao;
import io.chenglicun.modules.clc.dao.ClcQuestionBankDao;
import io.chenglicun.modules.clc.dto.*;
import io.chenglicun.modules.clc.entity.ClcExamReleaseEntity;
import io.chenglicun.modules.clc.entity.ClcExamResultEntity;
import io.chenglicun.modules.clc.entity.ClcQuestionBankEntity;
import io.chenglicun.modules.clc.service.*;
import io.chenglicun.modules.security.user.SecurityUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 考试发布
 *
 * @author HB 137664951@qq.com
 * @since 1.0 2023-10-18
 */
@Service
public class ClcExamReleaseServiceImpl extends CrudServiceImpl<ClcExamReleaseDao, ClcExamReleaseEntity, ClcExamReleaseDTO> implements ClcExamReleaseService {
    @Autowired
    private ClcExamReleaseQuestionService examReleaseQuestionService;
    @Autowired
    private ClcQuestionService questionService;
    @Autowired
    private ClcQuestionBankDao questionBankDao;
    @Autowired
    private ClcExamResultDao examResultDao;

    @Override
    public PageData<ClcExamReleaseDTO> page(Map<String, Object> params) {
        PageData<ClcExamReleaseDTO> page = super.page(params);
        List<ClcExamReleaseDTO> list = page.getList();
        List<Long> ids = list.stream().map(ClcExamReleaseDTO::getId).collect(Collectors.toList());
        ids.add(-1L);

        List<ClcExamResultEntity> entities = examResultDao.selectList(
                new QueryWrapper<ClcExamResultEntity>().lambda()
                        .eq(ClcExamResultEntity::getUserId, SecurityUser.getUserId())
                        .in(ClcExamResultEntity::getReleaseId, ids)
        );

        List<Long> bankIds = list.stream().map(ClcExamReleaseDTO::getBankId).filter(Objects::nonNull).collect(Collectors.toList());
        bankIds.add(-1L);

        List<ClcQuestionBankEntity> bankEntities = questionBankDao.selectList(new QueryWrapper<ClcQuestionBankEntity>().lambda().in(ClcQuestionBankEntity::getId, bankIds));

        for (ClcExamReleaseDTO releaseDTO : list) {
            List<ClcExamResultEntity> collect = entities.stream().filter(t -> releaseDTO.getId().equals(t.getReleaseId())).collect(Collectors.toList());
            releaseDTO.setExamResultList(ConvertUtils.sourceToTarget(collect, ClcExamResultDTO.class));

            ClcQuestionBankEntity bankEntity = bankEntities.stream().filter(t -> t.getId().equals(releaseDTO.getBankId())).findFirst().orElse(null);
            releaseDTO.setBankName(bankEntity == null ? null : bankEntity.getName());
        }

        return page;
    }

    @Override
    public QueryWrapper<ClcExamReleaseEntity> getWrapper(Map<String, Object> params){
        QueryWrapper<ClcExamReleaseEntity> wrapper = new QueryWrapper<>();


        return wrapper;
    }

    @Override
    public ClcExamReleaseDTO get(Long id) {
        ClcExamReleaseDTO dto = super.get(id);

        ClcQuestionBankEntity bankEntity = questionBankDao.selectById(dto.getBankId());
        dto.setBankName(bankEntity.getName());

        List<ClcExamReleaseQuestionDTO> list = examReleaseQuestionService.getListByExamReleaseId(dto.getId());
        dto.setExamReleaseQuestionList(list);

        return dto;
    }

    @Override
    @Transactional
    public void save(ClcExamReleaseDTO dto) {
        List<ClcQuestionDTO> questionList = questionService.getByBankIds(dto.getBankId());

        List<ClcExamReleaseQuestionDTO> list = new ArrayList<>();
        questionList.forEach(t -> {
            ClcExamReleaseQuestionDTO examReleaseQuestionDTO = new ClcExamReleaseQuestionDTO();
            examReleaseQuestionDTO.setQuestionId(t.getId());
            list.add(examReleaseQuestionDTO);
        });

        int scoreTotal = questionList.stream().mapToInt(ClcQuestionDTO::getScore).sum();

        dto.setScoreTotal(scoreTotal);
        super.save(dto);

        list.forEach(t -> t.setReleaseId(dto.getId()));
        examReleaseQuestionService.saveBatch(list);
    }

    @Override
    @Transactional
    public void update(ClcExamReleaseDTO dto) {

        examReleaseQuestionService.deleteByReleaseIds(dto.getId());


        List<ClcQuestionDTO> questionList = questionService.getByBankIds(dto.getBankId());

        List<ClcExamReleaseQuestionDTO> list = new ArrayList<>();
        questionList.forEach(t -> {
            ClcExamReleaseQuestionDTO examReleaseQuestionDTO = new ClcExamReleaseQuestionDTO();
            examReleaseQuestionDTO.setQuestionId(t.getId());
            list.add(examReleaseQuestionDTO);
        });

        int scoreTotal = questionList.stream().mapToInt(ClcQuestionDTO::getScore).sum();

        dto.setScoreTotal(scoreTotal);
        super.update(dto);

        list.forEach(t -> t.setReleaseId(dto.getId()));
        examReleaseQuestionService.saveBatch(list);
    }

    @Override
    @Transactional
    public void delete(Long[] ids) {
        super.delete(ids);

        examReleaseQuestionService.deleteByReleaseIds(ids);
    }
}